using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using ImageCSharp.Core.Events;
using ImageCSharp.Core.Interfaces;
using ImageCSharp.Core.Models;
using ImageCSharp.Core.Services;
using Microsoft.Win32;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace ImageCSharp.ViewModels
{
    /// <summary>
    /// 主窗口ViewModel
    /// </summary>
    public partial class MainViewModel : ObservableObject, 
        IRecipient<StatusMessageEvent>,
        IRecipient<SelectionChangedEvent>,
        IRecipient<ZoomLevelChangedEvent>,
        IRecipient<HistoryChangedEvent>,
        IRecipient<ImageDocumentChangedEvent>
    {
        private readonly IImageService _imageService;
        private readonly IPluginService _pluginService;
        private readonly IToolService _toolService;
        private readonly IHistoryService _historyService;
        private readonly IBatchProcessingService _batchService;

        [ObservableProperty]
        private ImageDocument? _currentDocument;

        [ObservableProperty]
        private Tool? _selectedTool;

        [ObservableProperty]
        private string _statusMessage = "Ready";

        [ObservableProperty]
        private ObservableCollection<Tool> _tools = new();

        [ObservableProperty]
        private ObservableCollection<string> _recentFiles = new();

        [ObservableProperty]
        private ObservableCollection<IFilterPlugin> _availableFilters = new();

        [ObservableProperty]
        private ObservableCollection<HistoryItem> _historyItems = new();

        [ObservableProperty]
        private bool _isToolboxVisible = true;

        [ObservableProperty]
        private bool _isPropertiesVisible = true;

        [ObservableProperty]
        private bool _isHistoryVisible = true;

        [ObservableProperty]
        private ImageStatistics? _imageStatistics;

        public MainViewModel(
            IImageService imageService,
            IPluginService pluginService,
            IToolService toolService,
            IHistoryService historyService,
            IBatchProcessingService batchService)
        {
            _imageService = imageService;
            _pluginService = pluginService;
            _toolService = toolService;
            _historyService = historyService;
            _batchService = batchService;

            // 注册消息接收
            WeakReferenceMessenger.Default.RegisterAll(this);

            // 初始化工具
            InitializeTools();

            // 初始化插件
            InitializePlugins();

            // 初始化历史记录
            InitializeHistory();

            // 创建新文档
            NewDocument();
        }

        private void InitializeTools()
        {
            // 从工具服务获取所有可用工具
            var availableTools = _toolService.GetAvailableTools();
            foreach (var tool in availableTools)
            {
                Tools.Add(tool);
            }

            // 设置默认工具
            if (Tools.Count > 0)
            {
                SelectedTool = Tools[0];
                _toolService.SelectTool(SelectedTool);
            }
        }

        private void InitializePlugins()
        {
            // 获取所有可用的滤镜插件
            var filters = _pluginService.GetFilterPlugins();
            foreach (var filter in filters)
            {
                AvailableFilters.Add(filter);
            }
        }

        private void InitializeHistory()
        {
            // 初始化历史记录
            var history = _historyService.GetHistory();
            foreach (var item in history)
            {
                HistoryItems.Add(item);
            }
        }

        #region Commands

        [RelayCommand]
        private void NewDocument()
        {
            CurrentDocument = new ImageDocument();
            StatusMessage = "New document created";
            WeakReferenceMessenger.Default.Send(new ImageDocumentChangedEvent(CurrentDocument));
        }

        [RelayCommand]
        private void OpenFile()
        {
            var openFileDialog = new OpenFileDialog
            {
                Filter = "Image Files|*.jpg;*.jpeg;*.png;*.bmp;*.gif;*.tiff|All Files|*.*",
                Title = "Open Image File"
            };

            if (openFileDialog.ShowDialog() == true)
            {
                try
                {
                    CurrentDocument = new ImageDocument(openFileDialog.FileName);
                    StatusMessage = $"Opened: {openFileDialog.FileName}";
                    WeakReferenceMessenger.Default.Send(new ImageDocumentChangedEvent(CurrentDocument));
                    
                    // 添加到最近文件列表
                    if (!_recentFiles.Contains(openFileDialog.FileName))
                    {
                        _recentFiles.Insert(0, openFileDialog.FileName);
                        if (_recentFiles.Count > 10)
                            _recentFiles.RemoveAt(_recentFiles.Count - 1);
                    }
                }
                catch (Exception ex)
                {
                    StatusMessage = $"Error opening file: {ex.Message}";
                }
            }
        }

        [RelayCommand]
        private void SaveFile()
        {
            if (CurrentDocument == null) return;

            if (string.IsNullOrEmpty(CurrentDocument.FilePath))
            {
                SaveFileAs();
                return;
            }

            try
            {
                _imageService.SaveImage(CurrentDocument, CurrentDocument.FilePath);
                CurrentDocument.IsModified = false;
                StatusMessage = $"Saved: {CurrentDocument.FilePath}";
            }
            catch (Exception ex)
            {
                StatusMessage = $"Error saving file: {ex.Message}";
            }
        }

        [RelayCommand]
        private void SaveFileAs()
        {
            if (CurrentDocument == null) return;

            var saveFileDialog = new SaveFileDialog
            {
                Filter = "PNG Files|*.png|JPEG Files|*.jpg|BMP Files|*.bmp|All Files|*.*",
                Title = "Save Image As",
                FileName = CurrentDocument.Name
            };

            if (saveFileDialog.ShowDialog() == true)
            {
                try
                {
                    _imageService.SaveImage(CurrentDocument, saveFileDialog.FileName);
                    CurrentDocument.FilePath = saveFileDialog.FileName;
                    CurrentDocument.IsModified = false;
                    CurrentDocument.Name = Path.GetFileNameWithoutExtension(saveFileDialog.FileName);
                    StatusMessage = $"Saved: {saveFileDialog.FileName}";
                }
                catch (Exception ex)
                {
                    StatusMessage = $"Error saving file: {ex.Message}";
                }
            }
        }

        [RelayCommand]
        private void Exit()
        {
            System.Windows.Application.Current.Shutdown();
        }

        [RelayCommand]
        private void ShowAbout()
        {
            var aboutWindow = new Views.AboutWindow();
            aboutWindow.Owner = System.Windows.Application.Current.MainWindow;
            aboutWindow.ShowDialog();
        }

        [RelayCommand]
        private void Undo()
        {
            if (_historyService.CanUndo)
            {
                if (_historyService.Undo())
                {
                    // 获取上一个历史记录状态
                    var history = _historyService.GetHistory();
                    var currentHistory = history.FirstOrDefault(h => h.IsActive);
                    if (currentHistory != null && currentHistory.State != null)
                    {
                        CurrentDocument = currentHistory.State.Clone();
                        WeakReferenceMessenger.Default.Send(new ImageDocumentChangedEvent(CurrentDocument));
                        StatusMessage = $"Undo: {currentHistory.Action}";
                    }
                }
                else
                {
                    StatusMessage = "Cannot undo";
                }
            }
            else
            {
                StatusMessage = "Nothing to undo";
            }
        }

        [RelayCommand]
        private void Redo()
        {
            if (_historyService.CanRedo)
            {
                if (_historyService.Redo())
                {
                    // 获取下一个历史记录状态
                    var history = _historyService.GetHistory();
                    var currentHistory = history.FirstOrDefault(h => h.IsActive);
                    if (currentHistory != null && currentHistory.State != null)
                    {
                        CurrentDocument = currentHistory.State.Clone();
                        WeakReferenceMessenger.Default.Send(new ImageDocumentChangedEvent(CurrentDocument));
                        StatusMessage = $"Redo: {currentHistory.Action}";
                    }
                }
                else
                {
                    StatusMessage = "Cannot redo";
                }
            }
            else
            {
                StatusMessage = "Nothing to redo";
            }
        }

        [RelayCommand]
        private void ZoomIn()
        {
            if (CurrentDocument != null)
            {
                CurrentDocument.ZoomLevel = Math.Min(CurrentDocument.ZoomLevel * 1.2f, 10.0f);
                WeakReferenceMessenger.Default.Send(new ZoomLevelChangedEvent(CurrentDocument.ZoomLevel));
                StatusMessage = $"Zoom: {CurrentDocument.ZoomLevel:P0}";
            }
        }

        [RelayCommand]
        private void ZoomOut()
        {
            if (CurrentDocument != null)
            {
                //CurrentDocument.ZoomLevel = Math.Max(CurrentDocument.ZoomLevel / 1.2f, 0.1f);
				// 移除最小缩放限制，允许持续缩小
                CurrentDocument.ZoomLevel = CurrentDocument.ZoomLevel / 1.2f;
                WeakReferenceMessenger.Default.Send(new ZoomLevelChangedEvent(CurrentDocument.ZoomLevel));
                StatusMessage = $"Zoom: {CurrentDocument.ZoomLevel:P0}";
            }
        }

        [RelayCommand]
        private void ActualSize()
        {
            if (CurrentDocument != null)
            {
                CurrentDocument.ZoomLevel = 1.0f;
                WeakReferenceMessenger.Default.Send(new ZoomLevelChangedEvent(CurrentDocument.ZoomLevel));
                StatusMessage = "Actual Size";
            }
        }

        [RelayCommand]
        private void FitToWindow()
        {
            // 适应窗口大小逻辑将在视图中处理
            StatusMessage = "Fit to Window";
        }

        [RelayCommand]
        private void SelectTool(Tool? tool)
        {
            if (tool != null)
            {
                SelectedTool = tool;
                _toolService.SelectTool(tool);
                WeakReferenceMessenger.Default.Send(new ToolChangedEvent(tool));
                StatusMessage = $"Selected tool: {tool.Name}";
            }
        }

        [RelayCommand]
        private void ToggleToolbox()
        {
            IsToolboxVisible = !IsToolboxVisible;
        }

        [RelayCommand]
        private void ToggleProperties()
        {
            IsPropertiesVisible = !IsPropertiesVisible;
        }

        [RelayCommand]
        private void ToggleHistory()
        {
            IsHistoryVisible = !IsHistoryVisible;
        }

        [RelayCommand]
        private void ApplyFilter(IFilterPlugin? filter)
        {
            if (filter == null || CurrentDocument == null)
                return;

            try
            {
                // 保存当前状态到历史记录
                _historyService.AddHistoryItem($"应用滤镜: {filter.Name}", CurrentDocument);

                // 应用滤镜
                //_imageService.ApplyFilter2(CurrentDocument, filter);
                CurrentDocument = _imageService.ApplyFilter2(CurrentDocument, filter);

                // 触发文档变更事件
                WeakReferenceMessenger.Default.Send(new ImageDocumentChangedEvent(CurrentDocument));

                // 更新统计信息
                UpdateImageStatistics();
                
                StatusMessage = $"Applied filter: {filter.Name}";
            }
            catch (Exception ex)
            {
                StatusMessage = $"Error applying filter: {ex.Message}";
            }
        }

        [RelayCommand]
        private void ShowImageStatistics()
        {
            if (CurrentDocument == null)
                return;

            UpdateImageStatistics();
            
            // 这里可以打开一个统计窗口或更新统计面板
            StatusMessage = "Image statistics updated";
        }

        [RelayCommand]
        private void BatchProcess()
        {
            var settingsWindow = new Views.BatchSettingsWindow(_pluginService);
            if (settingsWindow.ShowDialog() == true)
            {
                var config = settingsWindow.Configuration;
                try
                {
                    _batchService.Configuration = config;
                    _batchService.ProgressChanged += (s, e) =>
                    {
                        StatusMessage = $"Processing: {e.ProcessedCount}/{e.TotalCount} - {e.CurrentFile}";
                    };
                    
                    _batchService.BatchCompleted += (s, e) =>
                    {
                        StatusMessage = $"Batch completed: {e.ProcessedCount} processed, {e.FailedCount} failed";
                        if (e.FailedFiles.Any())
                        {
                            System.Windows.MessageBox.Show($"Failed files:\n{string.Join("\n", e.FailedFiles.Take(5))}", 
                                "Batch Processing Errors", MessageBoxButton.OK, MessageBoxImage.Warning);
                        }
                    };
                    
                    _batchService.StartBatchProcessing(config.InputDirectory, config.OutputDirectory);
                    StatusMessage = "Batch processing started...";
                }
                catch (Exception ex)
                {
                    StatusMessage = $"Batch processing error: {ex.Message}";
                }
            }
        }

        private void UpdateImageStatistics()
        {
            if (CurrentDocument == null)
                return;

            ImageStatistics = _imageService.GetStatistics(CurrentDocument);
        }

        private void BatchProcessImages(string directory)
        {
            var imageFiles = Directory.GetFiles(directory, "*.jpg")
                .Concat(Directory.GetFiles(directory, "*.png"))
                .Concat(Directory.GetFiles(directory, "*.bmp"))
                .ToArray();

            int processed = 0;
            foreach (var file in imageFiles)
            {
                try
                {
                    var document = _imageService.LoadImage(file);
                    
                    // 应用默认滤镜（例如高斯模糊）
                    if (AvailableFilters.FirstOrDefault() is IFilterPlugin filter)
                    {
                        _imageService.ApplyFilter(document, filter);
                    }
                    
                    // 调整大小
                    _imageService.ResizeImage(document, 800, 600);
                    
                    // 保存
                    var outputFile = Path.Combine(directory, "processed", Path.GetFileName(file));
                    Directory.CreateDirectory(Path.GetDirectoryName(outputFile)!);
                    _imageService.SaveImage(document, outputFile);
                    
                    processed++;
                    StatusMessage = $"Batch processing: {processed}/{imageFiles.Length}";
                }
                catch (Exception ex)
                {
                    StatusMessage = $"Error processing {Path.GetFileName(file)}: {ex.Message}";
                }
            }
        }

        #endregion

        public void Receive(StatusMessageEvent message)
        {
            StatusMessage = message.Value;
        }

        public void Receive(SelectionChangedEvent message)
        {
            if (CurrentDocument != null)
            {
                CurrentDocument.SelectionArea = message.Value;
                StatusMessage = $"Selection: {message.Value.Width:0}x{message.Value.Height:0}";
            }
        }

        public void Receive(ZoomLevelChangedEvent message)
        {
            StatusMessage = $"Zoom: {message.Value:P0}";
        }

        public void Receive(HistoryChangedEvent message)
        {
            StatusMessage = message.Value;
            
            // 更新历史记录列表
            HistoryItems.Clear();
            foreach (var item in _historyService.GetHistory())
            {
                HistoryItems.Add(item);
            }
        }

        public void Receive(ImageDocumentChangedEvent message)
        {
            CurrentDocument = message.Value;
            StatusMessage = $"Image: {CurrentDocument?.Image.Width ?? 0}x{CurrentDocument?.Image.Height ?? 0}";
            
            // 更新图像统计信息
            UpdateImageStatistics();
        }
        protected virtual void OnPropertyChanged(string propertyName)
        {
            base.OnPropertyChanged(propertyName);
        }
    }
}